/***********************************************************************************************//**
*\n  @file       app_can.c
*\n  @brief      app_can模块,主文件
*\n  @details
*\n -----------------------------------------------------------------------------------
*\n  文件说明：
*\n       1. app_can模块, 启动接口
*\n
*\n -----------------------------------------------------------------------------------
*\n  版本:    修改人:       修改日期:          描述:
*\n  V0.01  罗先能        2021.5.10      创建
*\n
***************************************************************************************************/

/**************************************************************************************************
* 头文件
***************************************************************************************************/
#include "hal.h"
#include "framework.h"

#include "app_can.h"
#include "can_recv.h"
#include "can_send.h"
#include "netcan.h"

#undef   DEBUG_LEVEL
#define  DEBUG_LEVEL  5
#include "vdebug.h"

/**************************************************************************************************
* 宏定义、结构定义
***************************************************************************************************/


/**************************************************************************************************
* 全局变量声明、定义
***************************************************************************************************/


/**************************************************************************************************
* 私有变量声明、定义
***************************************************************************************************/
TMsg  tMsg1 =
{
	.can_no     = 0,		// 0 =can0, 1= can1
	.can_kbps   = 500,      // kbps
	.can_type   = 0,        //
	.can_msg_id = 0,
	.can_msg    = { 0 },
};


/**************************************************************************************************
* 私有函数声明、定义
***************************************************************************************************/
static void usage(char *name )
{
	printf("--------- Can0/Can1 Test ---------------------\n");
	printf("Usage:\n");
	printf("send frame: %s wr   <can_no> <filename>\n", name);
	printf("loop frame: %s loop <can_no> <Kbps> <delay_ms> <loop_cnts> <id,dat0,data2...> \n", name);
	printf("read frame: %s rd   <can_no> <Kbps>    \n", name);
	printf(" <can_no>    - 0 = can0 ,1= can1\n");
	printf(" <Kbps>      - 50 ~ 1000 (kbps) \n");
	printf(" <delay_ms>  - interval time (ms)\n");
	printf(" <loop_cnts> - loop send counters; -1=continue send\n");
	printf(" <filename>  - send can massage from file \n");
	printf("\n");
}

/**************************************************************************************************
* 全局函数声明、定义
***************************************************************************************************/


// 启动app can模块
int AppCanStart(int argc, char *argv[])
{
	int ret;

	if (argc < 2)
	{
		usage(argv[0]);
		return -1;
	}
	else if (strcmp(argv[1],  "rd") == 0)  // 读取CAN报文 ---------------------
	{
		if (argc != 4)
		{
			usage(argv[0]);
			return -1;
		}

		if (strcmp(argv[2],  "0") == 0)
			tMsg1.can_no = 0;
		else if(strcmp(argv[2], "1") == 0)
			tMsg1.can_no= 1;
		else
		{
			usage(argv[0]);
			return -1;
		}

		tMsg1.can_kbps = atoi(argv[3]);
		if (tMsg1.can_kbps < 50)
		{
			printf("error: bitrate = %s kbps \n\n", argv[2]);
			usage(argv[0]);
			return -1;
		}

		can_start_input(NULL);

		while(1)
		{
			char key = getchar();
			if ((key == 'q') || (key == 'Q'))
			{
			    exit(0);
			}
			pause();
		}
	}
	else if (strcmp(argv[1],  "wr") == 0)  // 发送can报文 --------------------
	{

		if (argc != 4)
		{
			usage(argv[0]);
			return -1;
		}
		tMsg1.can_no   = atoi(argv[2]);
		char *filename = argv[3];
		can_send(tMsg1.can_no, filename);
	}
	else if (strcmp(argv[1],  "loop") == 0) // 循环发送can报文 ---------------
	{
		if (argc != 7)
		{
			usage(argv[0]);
			return -1;
		}

		int delay_ms;
		int loop_cnt;

		tMsg1.can_no   = strtoul(argv[2], NULL, 0);
		tMsg1.can_kbps = strtoul(argv[3], NULL, 0);
		delay_ms       = strtoul(argv[4], NULL, 0);
		loop_cnt       = strtoul(argv[5], NULL, 0);
		// 解析命令行参数
		char *pStr  = argv[6];
		char *pData = argv[6];
		char *p     = argv[6];
		int  len    = strlen(argv[6]);
		for(int i=0; i<9; i++)
		{
			/// 判断结束
			if(pData >= pStr+len)
				break;

			if(i==0) // can_id;
			{
				p = strchr(pData, ',');
				if (p != NULL)
					*p = '\0';
				tMsg1.can_msg_id = strtoul(pData, NULL, 0);
				if (p != NULL)
					pData = p+1;
				else
					break;
			}
			else  // data
			{
				p = strchr(pData, ',');
				if (p != NULL)
					*p = '\0';
				tMsg1.can_msg[i-1] = strtoul(pData, NULL, 0);
				if (p != NULL)
					pData = p+1;
				else
					break;
			}

		}

		static struct can_handle handle;
		if(tMsg1.can_no == 0)
			ret = netcan_open("can0", tMsg1.can_kbps*1000, 0, NULL, &handle);
		else if(tMsg1.can_no == 1)
			ret = netcan_open("can1", tMsg1.can_kbps*1000, 0, NULL, &handle);
		else
		{
			debug_error("tMsg.can_no == %d\n", tMsg1.can_no);
			return -1;
		}

		for(u32 i=0; i< (u32)loop_cnt; i++)
		{
			static u32 index = 0;
			index++;
			if (loop_cnt == -1)  // -1 表示一直循环发送,不停止
			{
				i = 0;
			}
			usleep(delay_ms * 1000);
			int ret =netcan_write(&handle, tMsg1.can_msg_id | CAN_EXTEND_FLAG, tMsg1.can_msg, 8);
			if (ret < 0)
			{
				debug_error("<%08d> error: %s\n", index, strerror(errno));
				continue;
			}
			printf("<%08d> tx[ 0x%08x 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x ]\n",
			        index, tMsg1.can_msg_id,
			        tMsg1.can_msg[0],tMsg1.can_msg[1], tMsg1.can_msg[2],tMsg1.can_msg[3],
			        tMsg1.can_msg[4],tMsg1.can_msg[5], tMsg1.can_msg[6],tMsg1.can_msg[7]);

			tMsg1.can_msg[0]++;
		}
	}
	else
	{
		usage(argv[0]);
		return -1;
	}
  	return(0);
}

